<!--
 * @Author       : wfl
 * @LastEditors: ww
 * @description  :
 * @updateInfo   :
 * @Date         : 2022-11-30 12:02:12
 * @LastEditTime: 2023-06-30 16:10:13
-->
<script lang="ts" setup name="ConditionGroupItemConfig">
import { Delete, Plus, Remove } from '@element-plus/icons-vue'
import OrgItems from '@main/views/approve-workflow/WorkFlow/OrgItems.vue'
import { _ } from 'iking-utils'
import { computed, reactive, ref } from 'vue'
import { IkingPicker } from 'iking-web-ui'
import { EComparatorType, EFlowFormType, EFormatDate } from '@main/views/approve-workflow/enum'
import { ValueType, WidgetTypeToValueType } from '../params'
const flowStore = useFlowStore()

const state = reactive({
  selectField: {},
  pickerModel: '',
  showPicker: false,
  users: [] as any[],
  orgType: 'user',
  // groupConditions: [],
  groupNames: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
  supportTypes: [
    ValueType.number,
    ValueType.string,
    ValueType.date,
    ValueType.dept,
    ValueType.user,
    ValueType.time,
    ValueType.input,
    ValueType.select
  ],
  explains: Object.entries(EComparatorType).map(([label, value]) => {
    return {
      label,
      value
    }
  }),
  dateTypes: Object.entries(EDateType).map(([label, value]) => {
    return {
      label,
      value
    }
  }),
  dateFormat: Object.entries(EFormatDate).map(([label, value]) => {
    return {
      label,
      value
    }
  })
  // { label: "x < 值 < x", value: "B" },
  // { label: "x ≤ 值 < x", value: "AB" },
  // { label: "x < 值 ≤ x", value: "BA" },
  // { label: "x ≤ 值 ≤ x", value: "ABA" },
})

const route = useRoute()
const { baseUrl } = useHttpUrl()
const token = useToken()

const selectedNode = computed(() => flowStore.selectedNode)
const formItems = computed(() => flowStore.design.formItems)
const formMap = computed(() => {
  const map = new Map()
  formItems.value?.forEach((item: any) => itemToMap(map, item))
  return map
})
const conditionList = computed(() => {
  // 构造可用条件选项
  let conditionItems: any[] = []
  if (route.query.type === EFlowFormType.已有表单) {
    /**
     * @description: filter作用，仅必填项可以作为条件配置
     * @param {*} _
     * @return {*}
     */
    conditionItems = _.cloneDeep(formItems.value?.filter((v: any) => v.required)).map((item: any) => {
      return {
        title: item.widgetLabel,
        id: item.widgetName,
        // 组件类型转换为实际值类型
        valueType: WidgetTypeToValueType(item.widgetType)
      }
    })
  }
  else {
    formItems.value?.forEach((item: any) => filterCondition(item, conditionItems))
    if (conditionItems.length === 0 || conditionItems[0].id !== 'root')
      conditionItems.unshift({ id: 'root', title: '发起人', valueType: 'User' })
  }

  return conditionItems
})

const itemToMap = (
  map: Map<any, any>,
  item: { id: any; name: string; props: { items: any[]; }; }
) => {
  map.set(item.id, item)
  if (item.name === 'SpanLayout')
    item.props.items.forEach(sub => itemToMap(map, sub))
}
const isSelect = (formId: any) => {
  const form = formMap.value.get(formId)
  if (form && (form.name === 'SelectInput' || form.name === 'MultipleSelect' || form.type === 'select'))
    return true

  return false
}
const getOptions = (formId: any) => {
  const widget = formMap.value.get(formId)
  return widget?.options?.optionItems || widget.props.options || []
}
const conditionValType = (type: any) => {
  switch (type) {
    case 'LESS':
    case 'LESS_EQUAL':
    case 'GREATER':
    case 'GREATER_EQUA':
    case 'EQUAL':
      return 0
    case 'IN':
      return 1
    default:
      return 2
  }
}
const chooseType = ref('')
const selectUser = (value: never[], type?: string) => {
  chooseType.value = type || ''
  state.selectField = value
  state.showPicker = true
}
const filterCondition = (
  item: {
    name: string
    props: { items: any[]; required: any; }
    valueType: string
    title: any
    id: any
    type: string
    options: {
      name: string
      type: string
      [key: string]: string
    }
  },
  list: any[]
) => {
  if (item.name === 'SpanLayout') {
    item.props.items.forEach(sub => filterCondition(sub, list))
  }
  else if (state.supportTypes.includes(item.type) && item.options.required) {
    list.push({
      title: item.options.label || item.options.name,
      id: item.id,
      valueType: item.type
    })
  }
}
// const selected = (select: any[]) => {
//   state.users.length = 0
//   select.forEach((u: any) => state.users.push(u))
// }
const delGroup = (index: any) => {
  selectedNode.value.props.groups.splice(index, 1)
}
const rmSubCondition = (
  group: { cids: any[]; conditions: any[]; },
  index: any
) => {
  group.cids.splice(index, 1)
  group.conditions.splice(index, 1)
}
const conditionChange = (
  index: number,
  group: { cids: any[]; conditions: any[]; }
) => {
  // 判断新增的
  group.cids.forEach(cid => {
    if (group.conditions.findIndex(cd => cd.id === cid) < 0) {
      // 新增条件
      const condition = { ...conditionList.value[index] }
      condition.compare = ''
      condition.value = []
      group.conditions.push(condition)
    }
  })
  for (let i = 0; i < group.conditions.length; i++) {
    // 去除没有选中的
    if (!group.cids.includes(group.conditions[i].id))
      group.conditions.splice(i, 1)
  }
}

const handSelected = (val: any) => {
  (state.selectField as any).value = val?.list || []
}
const ComparatorType = EComparatorType
const canCompare = (type: string) => {
  return {
    compare: [ValueType.date, ValueType.number, ValueType.time].includes(type),
    isDate: [ValueType.date, ValueType.time].includes(type)
  }
}
</script>

<template>
  <b
    class="mb-[8px] block"
    style="color: var(--ik-text-color-regular);"
  >同时满足以下条件
  </b>
  <div
    v-for="(group, index) in selectedNode.props.groups"
    :key="`${index}_g`"
    class="group"
  >
    <div class="group-header">
      <span class="group-name">条件组 {{ state.groupNames[index] }}</span>
      <div class="group-operation">
        <el-popover
          placement="bottom-end"
          title="选择审批条件"
          width="500"
          trigger="click"
        >
          <!-- <div>以下条件将决定具体的审批流程</div> -->
          <el-checkbox-group v-model="group.cids" value-key="id">
            <el-checkbox
              v-for="(condition, cindex) in conditionList"
              :key="condition.id"
              :label="condition.id"
              @change="conditionChange(cindex, group)"
            >
              {{ condition.title }}
            </el-checkbox>
          </el-checkbox-group>
          <temolate v-if="!conditionList.length">
            当前表单内没有必填项，请配置后再添加
          </temolate>
          <template #reference>
            <el-icon>
              <Plus />
            </el-icon>
          </template>
        </el-popover>
        <el-icon class="is-delete" @click="delGroup(index)">
          <Delete />
        </el-icon>
      </div>
    </div>
    <div class="group-content">
      <p v-if="group.conditions.length === 0">
        点击右上角 + 为本条件组添加条件
      </p>
      <div v-else>
        <el-form ref="condition-form" label-position="left" label-width="80px">
          <div
            v-for="(condition, cindex) in group.conditions"
            :key="`${condition.id}_${cindex}`"
            class="group-condition"
          >
            <!-- 构建表达式 canCompare(condition.valueType).compare -->
            <el-form-item :label="condition.title">
              <!-- <ellipsis slot="label" hover-tip :content="condition.title" /> -->
              <template v-if="[ValueType.string, ValueType.input, ValueType.select].includes(condition.valueType)">
                <el-select
                  v-model="condition.compare"
                  placeholder="判断符"
                  style="width: 118px;"
                  @change="condition.value = []"
                >
                  <!-- <template v-if="!isSelect(condition.id)"> -->
                  <el-option label="等于" :value="ComparatorType.等于" />
                  <el-option label="包含在" :value="ComparatorType.完全包含" />
                  <!-- </template> -->
                  <!-- <template v-else>
                    <el-option
                      v-for="exp in state.explains"
                      :key="exp.value"
                      :label="exp.label"
                      :value="exp.value"
                    />
                  </template> -->
                </el-select>
                <span v-if="isSelect(condition.id)" class="split-span">
                  <el-select
                    v-if="condition.compare === ComparatorType.完全包含"
                    v-model="condition.value"
                    class="form-width"
                    clearable
                    multiple
                    placeholder="选择值"
                  >
                    <el-option
                      v-for="(option, oi) in getOptions(condition.id)"
                      :key="oi"
                      :label="option?.label || option"
                      :value="option?.value || option"
                    />
                  </el-select>
                  <el-select
                    v-else
                    v-model="condition.value[0]"
                    class="form-width"
                    clearable
                    placeholder="选择值"
                  >
                    <el-option
                      v-for="(option, oi) in getOptions(condition.id)"
                      :key="oi"
                      :label="option?.label || option"
                      :value="option?.value || option"
                    />
                  </el-select>
                </span>
                <span v-else class="split-span">
                  <el-input
                    v-if="condition.compare === ComparatorType.等于"
                    v-model.trim="condition.value[0]"
                    class="form-width"
                    placeholder="输入比较值"
                  />
                  <el-select
                    v-else
                    v-model="condition.value"
                    class="form-width"
                    multiple
                    clearable
                    filterable
                    allow-create
                    placeholder="输入可能包含的值"
                  />
                </span>
              </template>
              <template v-else-if="canCompare(condition.valueType).compare">
                <el-select
                  v-model="condition.compare"
                  placeholder="判断符"
                  style="width: 118px;"
                >
                  <el-option
                    v-for="exp in state.explains"
                    :key="exp.value"
                    :label="exp.label"
                    :value="exp.value"
                  />
                </el-select>
                <span class="split-span">
                  <template v-if="canCompare(condition.valueType).isDate">
                    <el-date-picker
                      v-model="condition.value[0]"
                      style="width: 155px;"
                      type="date"
                      clearable
                      :format="condition.datePattern"
                      :value-format="condition.datePattern"
                      placeholder="选择日期"
                    />
                    <el-select
                      v-model="condition.datePattern"
                      style="width: 155px;"
                      filterable
                      allow-create
                      clearable
                      placeholder="日期格式"
                    >
                      <el-option
                        v-for="exp in state.dateFormat"
                        :key="exp.value"
                        :label="exp.label"
                        :value="exp.value"
                      />
                    </el-select>
                  </template>
                  <template v-else>
                    <el-input
                      v-if="conditionValType(condition.compare) === 0"
                      v-model.trim="condition.value[0]"
                      class="form-width"
                      placeholder="输入比较值"
                      type="number"
                    />
                    <el-select
                      v-else-if="conditionValType(condition.compare) === 1"
                      v-model="condition.value"
                      class="form-width"
                      multiple
                      filterable
                      allow-create
                      placeholder="输入可能包含的值"
                    />
                    <span v-else class="split-span">
                      <el-input
                        v-model.trim="condition.value[0]"
                        style="width: 130px;"
                        type="number"
                        placeholder="输入比较值"
                      />
                      <span>
                        ~
                        <el-input
                          v-model.trim="condition.value[1]"
                          style="width: 130px;"
                          type="number"
                          placeholder="输入比较值"
                        />
                      </span>
                    </span>
                  </template>
                </span>
              </template>
              <template v-else-if="condition.valueType === ValueType.user">
                <OrgItems v-model="condition.value" />
                <el-button
                  size="small"
                  type="primary"
                  link
                  @click="selectUser(condition, 'user')"
                >
                  添加
                </el-button>
              </template>
              <template v-else-if="condition.valueType === ValueType.dept">
                <span
                  class="item-desc"
                  style="margin-right: 20px;"
                >为某部门 / 某部门下的部门</span>
                <el-button
                  size="small"
                  :icon="Plus"
                  type="primary"
                  @click="selectUser(condition.value, 'dept')"
                >
                  选择部门
                </el-button>
                <OrgItems v-model="condition.value" />
              </template>
              <span v-else-if="condition.valueType === ValueType.date"> </span>
            </el-form-item>

            <el-icon class="danger" @click="rmSubCondition(group, cindex)">
              <Remove />
            </el-icon>
          </div>
        </el-form>
      </div>
    </div>
  </div>
  <IkingPicker
    ref="refIkingPicker"
    v-model="state.pickerModel"
    v-model:show="state.showPicker"
    :api="{
      methods: 'post',
      url: `${baseUrl}/server/component/pick/mix`,
      headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        'Authorization': token,
      },
    }"
    :type-option="{
      dep: 'DEPT',
      user: 'USER',
      role: 'ROLE',
      post: 'POST',
    }"
    :prop-option="{
      name: 'elementName',
      id: 'elementId',
      type: 'elementType',
    }"
    @ok="handSelected"
  />
</template>

<style lang="scss" scoped>
.form-width {
  width: 280px;
}

.split-span{
  display: inline-block;
  margin-left: 8px;
}

.group {
  margin-bottom: 20px;
  color: var(--ik-pagin-text-color);
  overflow: hidden;
  border-radius: 4px;
  border: 1px solid var(--ik-border-color);

  .group-header {
    padding: 5px 10px;
    background: var(--ik-main-bg);
    position: relative;

    div {
      display: inline-block;
    }

    .group-name {
      // font-size: small;
    }

    .group-cp {
      // font-size: small;
      position: absolute;
      left: 100px;
      display: flex;
      top: 5px;
      justify-content: center;
      align-items: center;
    }

    .group-operation {
      position: absolute;
      right: 0;

      i {
        margin: 0 8px;
        cursor: pointer;

        &:hover {
          color: var(--el-color-primary);
        }

        &.is-delete{
          color: var(--el-color-danger);
        }
      }
    }
  }

  .group-content {
    padding: 10px 5px;

    p {
      text-align: center;
      // font-size: small;
    }

    .el-icon-delete {
      position: absolute;
      cursor: pointer;
      top: 12px;
      right: 0;
    }
  }

  .condition-title {
    display: block;
    width: 100px;
  }
}

.group-condition {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
  justify-content: space-between;

  .el-icon {
    cursor: pointer;
    transition: all 0.25s ease-in-out;

    &.danger:hover {
      color: var(--theme-danger);
    }
  }

  :deep(.el-form-item__content) {
    flex: 1;

    & > div {
      margin-top: 0 !important;
    }
  }

  :deep(.el-form-item) {
    align-items: center;
    margin-bottom: 0;
  }
}
</style>
